在Spring Boot應用程式中,有時你可能需要創建自定義的驗證規則來滿足特定的業務需求。Spring Validation提供了一個強大的機制,允許你創建自定義的驗證器來執行這些規則。本節將介紹如何創建和整合自定義驗證註解。
Spring Validation並未提供手機號碼的驗證註解,因此本範例將演示如何自定義一個註解,用於驗證台灣的手機號碼。
首先,創建一個自定義註解 @ValidPhoneNumber
:
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneNumberValidator.class)
public @interface ValidPhoneNumber {
String message() default "Invalid phone number";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
PhoneNumberValidator.class
,這意味著當使用 @ValidPhoneNumberA
註解時,會調用 PhoneNumberValidator
類來執行驗證邏輯。創建一個驗證器 PhoneNumberValidator
,用於執行驗證邏輯:
public class PhoneNumberValidator implements ConstraintValidator<ValidPhoneNumber, String> {
@Override
public void initialize(ValidPhoneNumber constraintAnnotation) {
}
@Override
public boolean isValid(String phoneNumber, ConstraintValidatorContext context) {
if (phoneNumber == null) {
return false;
}
// 定義規則:手機號碼必須以09開頭,總共10位數字
return phoneNumber.matches("^09\\d{8}$");
}
}
要在實體類中使用自定義手機號碼驗證規則,只需將我們剛才自定義註解 @ValidPhoneNumber
應用到手機號碼屬性上。如下:
public class UserProfile {
@ValidPhoneNumber
private String phoneNumber;
// 其他屬性和方法
}
最後,在你的控制器中使用自定義驗證器,透過@Valid
註解來觸發驗證。
@RestController
@RequestMapping("/api")
public class UserProfileController {
@PostMapping("/user-profile")
public ResponseEntity<String> createUserProfile(@RequestBody @Valid UserProfileRequest request, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
// 紀錄驗證錯誤
List<String> errorMessages = new ArrayList<>();
// 提取所有驗證錯誤的消息
for (FieldError error : bindingResult.getFieldErrors()) {
errorMessages.add(error.getDefaultMessage());
}
// 返回錯誤消息給给客戶端
return ResponseEntity.badRequest().body("Validation failed: " + String.join(", ", errorMessages));
}
// 驗證通過,執行保存用戶操作...
return ResponseEntity.ok("UserProfile created successfully");
}
}
在 Spring Validation 中,分組驗證是一種強大的技巧,它允許您根據不同的使用情境對同一個實體類的屬性進行差異化的數據驗證。這節將介紹 Spring Validation 中分組驗證的基本概念以及如何使用它來提高數據驗證的靈活性。
分組驗證通常在以下情境中大有作為:您可能希望對同一個實體類的不同屬性在不同的場景下進行驗證。例如,在使用者註冊過程中,您可能需要驗證使用者名稱、密碼等屬性,但在使用者資料更新時,僅需要驗證電子郵件地址和手機號碼的格式。這正是分組驗證的用武之地。
分組驗證允許您將驗證規則分為不同的組別,然後根據需要選擇性地驗證某個組別的規則。這使得數據驗證變得更加靈活,可應用於不同的業務操作。
要在Spring Validation中使用分組驗證,你需要執行以下步驟:
首先,你需要在你的實體類中定義驗證分組。這可以通過在驗證註解上使用 groups
屬性來實現。例如:
public class UserProfile {
@NotBlank(groups = {Registration.class, Update.class})
@Size(min = 2, max = 10)
private String username;
@NotBlank(groups = {Registration.class})
private String password;
@Email(groups = {Registration.class, Update.class})
private String email;
//使用第4小節所學的自定義驗證註解
@ValidPhoneNumbergroups = {Registration.class, Update.class}
private String phoneNumber;
// 定義驗證分組
public interface Registration {}
public interface Update {}
}
在上述範例中,我們定義了兩個驗證分組:Registration
和 Update
。不同的屬性根據需要被分配到這些組中。
對於 Registration.class
和 Update.class
這兩個分組,您需要自己在程式碼中創建它們。這些分組通常是 Java 中的 interface,且接口不需要定義任何方法,它只是用於標識相關的驗證分組,您可以在任何合適的包(package)中創建它們。
接下來,在你的控制器中,你可以通過在方法參數上使用@Validated
註解並指定要使用的分組來應用驗證分組。例如:
@RestController
@RequestMapping("/user")
public class UserController {
@PostMapping("/register")
public ResponseEntity<String> registerUser(@Validated(UserProfileRequest.Registration.class) @RequestBody UserProfileRequest userProfile) {
// 執行使用者註冊操作...
return ResponseEntity.ok("User registered successfully");
}
@PutMapping("/update")
public ResponseEntity<String> updateUser(@Validated(UserProfileRequest.Update.class) @RequestBody UserProfileRequest userProfile) {
// 執行使用者更新操作...
return ResponseEntity.ok("User updated successfully");
}
}
通過使用分組驗證,您可以更好地控制哪些屬性需要在不同的業務場景中進行驗證,從而提高了驗證的精確性和可維護性。這對於複雜的應用程式來說尤其有用。
在使用 Spring Validation 進行參數驗證時,當驗證失敗時,Spring Validation 會拋出 MethodArgumentNotValidException
異常。在本節中,我們將解釋如何處理這些異常以及如何自定義錯誤訊息,以提供更友善的使用者回饋。
當參數驗證失敗時,Spring Validation 會拋出 MethodArgumentNotValidException
異常。要捕獲和處理這些異常,你可以在控制器方法中使用 @ExceptionHandler
註解來定義異常處理程式。
以下是一個範例,演示如何在 Spring Boot 應用程式中捕獲數據驗證異常:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<String> handleValidationException(MethodArgumentNotValidException ex) {
return ResponseEntity.badRequest().body("參數驗證失敗:" + ex.getBindingResult().getFieldError().getDefaultMessage());
}
}
在上面的範例中,我們創建了一個全局異常處理程式 GlobalExceptionHandler
,並使用 @ExceptionHandler
註解定義了一個處理 MethodArgumentNotValidException
異常的方法。當參數驗證失敗時,此方法會返回一個自定義的錯誤訊息。
Spring Validation 允許你自訂錯誤訊息,以提供更友善的使用者回饋。你可以在驗證註解上使用 message
屬性,來指定錯誤訊息。在錯誤訊息中,你可以使用佔位符來參考驗證失敗的欄位和其他資訊。
public class Product {
@NotBlank(message = "產品名稱不能為空")
private String name;
@Positive(message = "價格必須是正數")
private double price;
// 省略其他屬性和方法
}
在上面的範例中,我們在 @NotBlank
註解中自訂了錯誤訊息 "產品名稱不能為空"
,在 @Positive
註解中自訂了錯誤訊息 "價格必須是正數"
。當參數驗證失敗時,將顯示這些自訂錯誤訊息。
自訂錯誤訊息可以協助提升使用者體驗,讓使用者更容易理解和解決問題。
透過異常處理和自訂錯誤訊息,你可以更好地處理參數驗證失敗的情況,並為使用者提供有用的回饋資訊,從而改善應用程式的品質和可用性。
在本篇中,我們深入探討了 Spring Validation 在 Spring Boot 應用程式中的應用,強調了數據驗證對於應用程式的穩健性和安全性的重要性。我們總結了以下關鍵知識點:
總的來說,數據驗證是確保應用程式品質和安全性的關鍵步驟之一。我們鼓勵讀者積極採用和實踐數據驗證技術,以提高數據品質和安全性,確保應用程式的穩健性和可用性。通過合理的數據驗證,可以有效減少無效數據帶來的問題,提高使用者滿意度,確保應用程式的可靠性。